home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 December / CHIPNET Aralık 1997.iso / linux / redhat / misc / src / install / earlym~1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-11  |  12.4 KB  |  516 lines

  1. #include <ctype.h>
  2. #include <errno.h>
  3. #include <fcntl.h>
  4. #include <newt.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <sys/mount.h>
  9. #include <unistd.h>
  10.  
  11. #include "hd.h"
  12. #include "fs.h"
  13. #include "install.h"
  14. #include "log.h"
  15. #include "methods.h"
  16. #include "net.h"
  17. #include "windows.h"
  18.  
  19. /* This was split into two pieces to keep the initial install program small */
  20.  
  21. static int nfsPrepare(struct installMethod * method);
  22. static int smbPrepare(struct installMethod * method);
  23. static int cdromPrepare(struct installMethod * method);
  24. int floppyRoot(struct installMethod * method);
  25. static int nfsGetSetup(char ** hostptr, char ** dirptr);
  26. static int smbGetSetup(char ** hostptr, char ** dirptr, char ** acctptr,
  27.             char ** pwptr);
  28. static int totalMemory(void);            /* in K */
  29. static int smbPrepare(struct installMethod * method);
  30.  
  31. static struct installMethod methods[] = {
  32.     { "Local CDROM",         "cdrom", 0, cdromPrepare, NULL, NULL,
  33.         NULL, NULL, NULL },
  34.     { "NFS image",         "nfs", 0, nfsPrepare, NULL, NULL,
  35.         NULL, NULL, NULL },
  36.     { "hard drive",        "hd", 0, floppyRoot, NULL, NULL,
  37.         NULL, NULL, NULL },
  38.     { "FTP",             "ftp", 0, floppyRoot, NULL, NULL,
  39.         NULL, NULL, NULL },
  40. #ifdef __i386__
  41.     { "SMB image",         "smb", 0, floppyRoot, NULL, NULL,
  42.         NULL, NULL, NULL },
  43. #endif
  44. #if 0
  45.     { "SCSI Tape Install",     "tape", 0, floppyRoot, NULL, NULL,
  46.         NULL, NULL, NULL },
  47. #endif
  48. } ;
  49. static int numMethods = sizeof(methods) / sizeof(struct installMethod);
  50.  
  51. #define LOAD_BLOCK_COUNT 16
  52. static int loadRamdisk(char * todev, char * fromdev, int blocks,
  53.             char * label) {
  54.     newtComponent form, scale;
  55.     char * topath, * frompath;
  56.     char buf[LOAD_BLOCK_COUNT * 1024];
  57.     int rc = 0;
  58.     int i;
  59.     int to, from;
  60.  
  61.     if (blocks % LOAD_BLOCK_COUNT) {
  62.     logMessage("internal error: blocks in loadRamdisk() must be "
  63.         "divisible by %d!!", LOAD_BLOCK_COUNT);
  64.     return 1;
  65.     }
  66.  
  67.     topath = alloca(strlen(todev) + 8);
  68.     sprintf(topath, "/tmp/%s", todev);
  69.  
  70.     frompath = alloca(strlen(fromdev) + 8);
  71.     sprintf(frompath, "/tmp/%s", fromdev);
  72.  
  73.     if (devMakeInode(todev, topath)) return 1;
  74.     if (devMakeInode(fromdev, frompath)) {
  75.     unlink(topath);
  76.     return 1;
  77.     }
  78.  
  79.     to = open(topath, O_WRONLY);
  80.     if (to < 0) {
  81.     logMessage("failed to open %s: %s", topath, strerror(errno));
  82.     unlink(topath);
  83.     unlink(frompath);
  84.     return 1;
  85.     }
  86.  
  87.     from = open(frompath, O_RDONLY);
  88.     if (from < 0) {
  89.     logMessage("failed to open %s: %s", frompath, strerror(errno));
  90.     unlink(topath);
  91.     unlink(frompath);
  92.     return 1;
  93.     }
  94.  
  95.     unlink(frompath);
  96.     unlink(topath);
  97.  
  98.     logMessage("copying %d blocks from %s to %s", blocks, fromdev, todev);
  99.  
  100.     newtOpenWindow(10, 10, 60, 5, "Loading");
  101.     
  102.     form = newtForm(NULL, NULL, 0);
  103.     
  104.     newtFormAddComponent(form, newtLabel(1, 1, label));
  105.     scale = newtScale(1, 3, 58, blocks / LOAD_BLOCK_COUNT);
  106.     newtFormAddComponent(form, scale);
  107.     newtDrawForm(form);
  108.     newtRefresh();
  109.  
  110.     for (i = 0; i < (blocks / LOAD_BLOCK_COUNT) && !rc; i++) {
  111.     newtScaleSet(scale, i);
  112.     newtRefresh();
  113.  
  114.     if (read(from, buf, sizeof(buf)) != sizeof(buf)) {
  115.         logMessage("error reading from device: %s", strerror(errno));
  116.         rc = 1;
  117.     } else {
  118.         if (write(to, buf, sizeof(buf)) != sizeof(buf)) {
  119.         logMessage("error writing to device: %s", strerror(errno));
  120.         rc = 1;
  121.         }
  122.     }
  123.     }
  124.  
  125.     newtPopWindow();
  126.     newtFormDestroy(form);
  127.     
  128.     close(from);
  129.     close(to);
  130.  
  131.     return rc;
  132. }
  133.  
  134. static int totalMemory(void) {
  135.     int fd;
  136.     int bytesRead;
  137.     char buf[4096];
  138.     char * chptr, * start;
  139.     int total = 0;
  140.  
  141.     fd = open("/proc/meminfo", O_RDONLY);
  142.     if (fd < 0) {
  143.     logMessage("failed to open /proc/meminfo: %s", strerror(errno));
  144.     return 0;
  145.     }
  146.  
  147.     bytesRead = read(fd, buf, sizeof(buf) - 1);
  148.     if (bytesRead < 0) {
  149.     logMessage("failed to read from /proc/meminfo: %s", strerror(errno));
  150.     close(fd);
  151.     return 0;
  152.     }
  153.  
  154.     close(fd);
  155.     buf[bytesRead] = '\0';
  156.  
  157.     chptr = buf;
  158.     while (*chptr && !total) {
  159.     if (*chptr != '\n' || strncmp(chptr + 1, "MemTotal:", 9)) {
  160.         chptr++;
  161.         continue;
  162.     }
  163.  
  164.     start = ++chptr ;
  165.     while (*chptr && *chptr != '\n') chptr++;
  166.  
  167.     *chptr = '\0';
  168.  
  169.     logMessage("found total memory tag: \"%s\"", start);
  170.     
  171.     while (!isdigit(*start) && *start) start++;
  172.     if (!*start) {
  173.         logMessage("no number appears after MemTotal tag");
  174.         return 0;
  175.     }
  176.  
  177.     chptr = start;
  178.     while (*chptr && isdigit(*chptr)) {
  179.         total = (total * 10) + (*chptr - '0');
  180.         chptr++;
  181.     }
  182.     }
  183.  
  184.     logMessage("%d kB are available", total);
  185.  
  186.     return total;
  187. }
  188.  
  189. static int installMethodWindow(struct installMethod ** method) {
  190.     newtComponent form, listbox, okay, text;
  191.     struct installMethod * newMethod;
  192.     int i;
  193.  
  194.     newtOpenWindow(21, 4, 38, 15, "Installation Method");
  195.  
  196.     form = newtForm(NULL, NULL, 0);
  197.  
  198.     text = newtTextbox(3, 1, 32, 2, NEWT_TEXTBOX_WRAP);
  199.     newtTextboxSetText(text, "What type of media contains the packages "
  200.             "to be installed?");
  201.  
  202.     listbox = newtListbox(12, 4, 0, NEWT_LISTBOX_RETURNEXIT);
  203.  
  204.     for (i = 0; i < numMethods; i++) {
  205.     newtListboxAddEntry(listbox, methods[i].name, methods + i);
  206.     }
  207.  
  208.     okay = newtButton(14, 11, "Ok");
  209.  
  210.     newtFormAddComponents(form, text, listbox, okay, NULL);
  211.  
  212.     newtRunForm(form);
  213.  
  214.     newMethod = newtListboxGetCurrent(listbox);
  215.  
  216.     newtFormDestroy(form);
  217.     newtPopWindow();
  218.  
  219.     *method = newMethod;
  220.  
  221.     return 0;
  222. }
  223.  
  224. int chooseInstallMethod(struct installMethod ** method) {
  225.     int rc;
  226.     do {
  227.     rc = installMethodWindow(method);
  228.     if (rc) return rc;
  229.  
  230.     if ((*method)->prepareImage) {
  231.         rc = (*method)->prepareImage((*method));
  232.         if (rc == INST_ERROR) return rc;
  233.     }
  234.     } while (rc);
  235.  
  236.     return 0;
  237. }
  238.  
  239. static int nfsGetSetup(char ** hostptr, char ** dirptr) {
  240.     newtComponent form, okay, cancel, siteEntry, dirEntry, answer, text;
  241.     char * site, * dir;
  242.  
  243.     if (*hostptr) {
  244.     site = *hostptr;
  245.     dir = *dirptr;
  246.     } else {
  247.     site = "";
  248.     dir = "";
  249.     }
  250.  
  251.     newtOpenWindow(15, 4, 50, 14, "NFS Setup");
  252.  
  253.     form = newtForm(NULL, NULL, 0);
  254.     okay = newtButton(10, 10, "Ok");
  255.     cancel = newtButton(30, 10, "Cancel");
  256.  
  257.     text = newtTextbox(1, 1, 47, 5, NEWT_TEXTBOX_WRAP);
  258.     newtTextboxSetText(text,
  259.     "Please enter the following information:\n"
  260.     "\n"
  261.     "    o the name or IP number of your NFS server\n"
  262.     "    o the directory on that server containing\n"
  263.     "      Red Hat Linux for your architecture");
  264.  
  265.     newtFormAddComponent(form, newtLabel(3, 7, "NFS server name  :"));
  266.     newtFormAddComponent(form, newtLabel(3, 8, "Red Hat directory:"));
  267.  
  268.     siteEntry = newtEntry(22, 7, site, 24, &site, NEWT_ENTRY_SCROLL);
  269.     dirEntry = newtEntry(22, 8, dir, 24, &dir, NEWT_ENTRY_SCROLL);
  270.  
  271.     newtFormAddComponents(form, text, siteEntry, dirEntry, okay, cancel, NULL);
  272.  
  273.     answer = newtRunForm(form);
  274.     if (answer == cancel) {
  275.     newtFormDestroy(form);
  276.     newtPopWindow();
  277.     
  278.     return INST_CANCEL;
  279.     }
  280.  
  281.     *hostptr = strdup(site);
  282.     *dirptr = strdup(dir);
  283.  
  284.     newtFormDestroy(form);
  285.     newtPopWindow();
  286.  
  287.     return 0;
  288. }
  289.  
  290. static int cdromPrepare(struct installMethod * method) {
  291.     char * cddev;
  292.     struct driversLoaded * dl = NULL;
  293.     static int moduleLoaded = 0;
  294.     int rc;
  295.  
  296.     messageWindow("Note", "Insert your Red Hat CD into your CD drive now");
  297.  
  298.     while (1) {
  299.     rc = setupCDdevice(&cddev, &dl);
  300.     if (rc) return rc;
  301.  
  302. #ifdef __i386__
  303.     if (!moduleLoaded) {
  304.         rc = loadModule("isofs", DRIVER_FS, DRIVER_MINOR_NONE, &dl);
  305.         if (rc) return rc;
  306.         moduleLoaded = 1;
  307.     }
  308. #endif
  309.  
  310.     rc = doMount(cddev, "/tmp/rhimage", "iso9660", 1, 0);
  311.     if (rc) {
  312.         removeCDmodule(&dl);
  313.         messageWindow("Error", 
  314.             "I could not mount a CD on device /dev/%s", cddev);
  315.         continue;
  316.     }
  317.  
  318.     if (access("/tmp/rhimage/RedHat", R_OK)) {
  319.         umount("/tmp/rhimage");
  320.         removeCDmodule(&dl);
  321.         messageWindow("Error", "That CDROM device does not seem "
  322.               "to contain a Red Hat CDROM.");
  323.         continue;
  324.     }
  325.  
  326.     break;
  327.     }
  328.  
  329.     if (!access("/tmp/rhimage/RedHat/instimage/lib", X_OK)) {
  330.     unlink("/tmp/rhimage/RedHat/instimage/lib");
  331.     symlink("/tmp/rhimage/RedHat/instimage/lib", "/lib");
  332.     }
  333.  
  334.     if (!access("/tmp/rhimage/RedHat/instimage/usr/bin", X_OK)) {
  335.         unlink("/tmp/rhimage/RedHat/instimage/usr/bin");
  336.     symlink("/tmp/rhimage/RedHat/instimage/usr/bin", "/usr/bin");
  337.     }
  338.  
  339.     writeModuleConf("/tmp", dl, 0);
  340.  
  341.     return 0;
  342. }
  343.  
  344. static int nfsPrepare(struct installMethod * method) {
  345.     struct netInterface intf;
  346.     struct netConfig netc;
  347.     struct driversLoaded * dl = NULL;
  348.     char * host = NULL, * dir = NULL;
  349.     char * buf;
  350.     static int moduleLoaded = 0;
  351.     enum { NFS_STEP_NET, NFS_STEP_INFO, NFS_STEP_MOUNT, NFS_STEP_DONE }
  352.         step = NFS_STEP_NET;
  353.     int rc;
  354.  
  355.     memset(&intf, 0, sizeof(intf));
  356.     memset(&netc, 0, sizeof(netc));
  357.  
  358.     while (step != NFS_STEP_DONE) {
  359.     switch (step) {
  360.       case NFS_STEP_NET:
  361.         rc = bringUpNetworking(&intf, &netc, &dl);
  362.         if (rc) return rc;
  363.         step = NFS_STEP_INFO;
  364.         break;
  365.  
  366.       case NFS_STEP_INFO:
  367.         rc = nfsGetSetup(&host, &dir);
  368.         if (rc == INST_CANCEL)
  369.         step = NFS_STEP_NET;
  370.         else if (rc == INST_ERROR)
  371.         return INST_ERROR;
  372.         else
  373.         step = NFS_STEP_MOUNT;
  374.         break;
  375.  
  376.       case NFS_STEP_MOUNT:
  377.         if (!strlen(host) || !strlen(dir))
  378.         rc = INST_ERROR;
  379.         else {
  380.         buf = malloc(strlen(host) + strlen(dir) + 10);
  381.         strcpy(buf, host);
  382.         strcat(buf, ":");
  383.         strcat(buf, dir);
  384.  
  385. #ifdef __i386__
  386.         if (!moduleLoaded) {
  387.             rc = loadModule("nfs", DRIVER_FS, DRIVER_MINOR_NONE, &dl);
  388.             if (rc) return rc;
  389.             moduleLoaded = 1;
  390.         }
  391. #endif
  392.  
  393.         rc = doMount(buf, "/tmp/rhimage", "nfs", 1, 0);
  394.         free(buf);
  395.         }
  396.  
  397.         if (rc) {
  398.         step = NFS_STEP_INFO;
  399.         messageWindow("Error", 
  400.             "I could not mount that directory from the server");
  401.         } else {
  402.             if (access("/tmp/rhimage/RedHat", R_OK)) {
  403.             step = NFS_STEP_INFO;
  404.             messageWindow("Error", "That directory does not seem "
  405.                   "to contain a Red Hat installation tree.");
  406.             umount("/tmp/rhimage");
  407.         } else
  408.             step = NFS_STEP_DONE;
  409.         }
  410.  
  411.         break;
  412.  
  413.       case NFS_STEP_DONE:
  414.         break;
  415.     }
  416.     }
  417.  
  418.     free(host);
  419.     free(dir);
  420.  
  421.     writeNetInterfaceConfig("/tmp", &intf);
  422.     writeNetConfig("/tmp", &netc, &intf, 1);
  423.     writeModuleConf("/tmp", dl, 0);
  424.  
  425.     if (!access("/tmp/rhimage/RedHat/instimage/lib", X_OK)) {
  426.     unlink("/tmp/rhimage/RedHat/instimage/lib");
  427.     symlink("/tmp/rhimage/RedHat/instimage/lib", "/lib");
  428.     }
  429.  
  430.     if (!access("/tmp/rhimage/RedHat/instimage/usr/bin", X_OK)) {
  431.         unlink("/tmp/rhimage/RedHat/instimage/usr/bin");
  432.     symlink("/tmp/rhimage/RedHat/instimage/usr/bin", "/usr/bin");
  433.     }
  434.  
  435.     return 0;
  436. }
  437.  
  438. int floppyRoot(struct installMethod * method) { 
  439.     newtComponent form, text, okay, cancel, answer;
  440.     static int isMounted = 0;
  441.  
  442.     if (isMounted) return 0;
  443.  
  444.     if (access("/usr/bin/runinstall2", R_OK)) {
  445.     newtOpenWindow(20, 4, 40, 15, "Second Floppy");
  446.  
  447.     text = newtTextbox(1, 1, 38, 5, NEWT_TEXTBOX_WRAP);
  448.     newtTextboxSetText(text, 
  449.         "This install method requires a second disk. Please remove "
  450.         "the boot disk currently in your drive and replace it with "
  451.         "the Red Hat Supplementary Install disk.");
  452.  
  453.     okay = newtButton(6, 10, "Ok");
  454.     cancel = newtButton(24, 10, "Cancel");
  455.  
  456.     form = newtForm(NULL, NULL, 0);
  457.     newtFormAddComponents(form, text, okay, cancel, NULL);
  458.       
  459.     answer = newtRunForm(form);
  460.  
  461.     newtFormDestroy(form);
  462.     newtPopWindow();
  463.  
  464.     if (answer == cancel) return INST_CANCEL;
  465.  
  466.     if (testing) return 0;
  467.  
  468.     while (doMount("fd0", "/tmp/image", "ext2", 1, 0) ||
  469.            access("/tmp/image/usr/bin/runinstall2", R_OK)) {
  470.         /* in case the mount succeeded */
  471.         umount("/tmp/image");
  472.  
  473.         newtOpenWindow(20, 4, 40, 15, "Second Floppy");
  474.         text = newtTextbox(1, 1, 38, 5, NEWT_TEXTBOX_WRAP);
  475.  
  476.         newtTextboxSetText(text, 
  477.         "I failed to mount the floppy. Please insert the "
  478.         "Red Hat Supplementary Install disk, or choose "
  479.         "Cancel to pick a different installation process.");
  480.  
  481.         okay = newtButton(6, 10, "Ok");
  482.         cancel = newtButton(24, 10, "Cancel");
  483.  
  484.         form = newtForm(NULL, NULL, 0);
  485.         newtFormAddComponents(form, text, okay, cancel);
  486.       
  487.         answer = newtRunForm(form);
  488.         
  489.         newtFormDestroy(form);
  490.         newtPopWindow();
  491.  
  492.         if (answer == cancel) return INST_CANCEL;
  493.     }
  494.  
  495.     if (totalMemory() > 8000) {
  496.         umount("/tmp/image");
  497.         loadRamdisk("ram2", "fd0", 1440, "Loading supplemental disk...");
  498.         if (doMount("ram2", "/tmp/image", "ext2", 1, 0)) {
  499.         errorWindow("Error mounting ramdisk. This shouldn't "
  500.                 "happen, and I'm rebooting your system now.");
  501.         exit(1);
  502.         }
  503.     }
  504.  
  505.  
  506.     symlink("/tmp/image/lib", "/lib");
  507.     symlink("/tmp/image/etc", "/etc");
  508.     symlink("/tmp/image/usr/bin", "/usr/bin");
  509.     }
  510.  
  511.     isMounted = 1;
  512.  
  513.     return 0;
  514. }
  515.  
  516.